import { FileService } from '@app/file';
import { HashService } from '@app/hash';
import { PrismaService } from '@app/prisma';
import { ShopEntity } from '@app/prisma/entitys/shop.entity';
import { UserEntity } from '@app/prisma/entitys/user.entity';
import { ForbiddenError } from '@nestjs/apollo';
import { UseGuards } from '@nestjs/common';
import { Args, Int, Mutation, Query, Resolver } from '@nestjs/graphql';
import { Prisma } from '@prisma/client';
import { GqlAuthPowerGuard, EditShopPower, GqlAuthGuard, CurrentUser } from 'src/auth/auth.guard';

@Resolver()
export class ShopResolver {
    constructor(
        private readonly prismaService: PrismaService,
        private readonly fileService: FileService,
        private readonly hashService: HashService
    ) { }

    @Query(() => ShopEntity)
    getShopDetial(
        @Args("id", { type: () => Int }) id: number
    ) {
        return this.prismaService.shop.findUnique({
            where: {
                id
            },
            include: {
                Goods: true,
                Comment: true
            }
        })
    }

    @Query(() => [ShopEntity])
    selShopList(
        @Args("address", { nullable: true }) address: string,
        @Args("order", { nullable: true }) order: string,
        @Args("keyword", { nullable: true }) keyword: string,
    ) {
        const where: Prisma.ShopWhereInput = {};
        if (!!address) where.address = address;
        const orderBy: any = {};
        if (order === "sales") {
            orderBy.count = "desc"
        } else if (order === "price") {
            orderBy.total = "asc"
        } else {
            orderBy.id = "desc"
        };
        if (!!keyword) {
            where.name = {
                contains: keyword
            }
        }
        return this.prismaService.shop.findMany({
            orderBy,
            where
        })
    }

    @Mutation(() => ShopEntity)
    @UseGuards(GqlAuthGuard)
    async addShop(
        @Args("name") name: string,
        @Args("phone") phone: string,
        @Args("avatar") avatar: string,
        @Args("businessHours") businessHours: string,
        @Args("threshold", { type: () => Int, nullable: true }) threshold: number,
        @Args("total", { type: () => Int, nullable: true }) total: number,
        @Args("information", { nullable: true }) information: string,
        @Args("address") address: string,
    ) {
        const hash_key = this.hashService.createUid()
        const user = await this.prismaService.user.findUnique({ where: { account: phone } });
        if (!!user) throw new ForbiddenError("改账号已存在")
        await this.prismaService.user.create({
            data: {
                account: phone,
                router: "shop",
                hash_key,
                name,
                profile: {
                    create: {
                        password: this.hashService.cryptoPassword(phone)
                    }
                }
            }
        })
        this.fileService.fileW2R(this.fileService.getShopAvatar(hash_key), Buffer.from(avatar, "base64"))
        return this.prismaService.shop.create({
            data: {
                name,
                threshold,
                total,
                hash_key,
                information,
                address,
                phone,
                businessHours,
            }
        })
    }

    @Mutation(() => ShopEntity)
    @UseGuards(GqlAuthGuard)
    async updShop(
        @Args("id", { type: () => Int }) id: number,
        @Args("name") name: string,
        @Args("phone") phone: string,
        @Args("avatar", { nullable: true }) avatar: string,
        @Args("businessHours") businessHours: string,
        @Args("threshold", { type: () => Int, nullable: true }) threshold: number,
        @Args("total", { type: () => Int, nullable: true }) total: number,
        @Args("information", { nullable: true }) information: string,
        @Args("address") address: string,
    ) {
        const { hash_key } = await this.prismaService.shop.findUniqueOrThrow({ where: { id } });
        const shop = await this.prismaService.shop.findUniqueOrThrow({
            where: {
                id
            }
        })
        const user = await this.prismaService.user.findUnique({ where: { account: shop.phone } });
        const target = await this.prismaService.user.findUnique({ where: { account: phone } })
        if (!!user) {
            if (!!target) throw new ForbiddenError("改手机号已被占用")
            await this.prismaService.user.update({
                where: {
                    id: user.id
                },
                data: {
                    account: phone,
                    router: "shop"
                }
            })
        } else if (!target) {
            await this.prismaService.user.create({
                data: {
                    account: phone,
                    router: "shop",
                    hash_key,
                    name,
                    profile: {
                        create: {
                            password: this.hashService.cryptoPassword(phone)
                        }
                    }
                }
            })
        }
        if (!!avatar) this.fileService.fileW2R(this.fileService.getShopAvatar(hash_key), Buffer.from(avatar, "base64"))
        return this.prismaService.shop.update({
            where: {
                id
            },
            data: {
                name,
                threshold,
                total,
                information,
                address,
                phone,
                businessHours,
            }
        })
    }

    @Mutation(() => ShopEntity)
    @UseGuards(GqlAuthGuard)
    delShop(
        @Args("id", { type: () => Int }) id: number
    ) {
        return this.prismaService.shop.delete({ where: { id } })
    }
}
